import $ = require("jquery");
import { v4 as uuidv4 } from "uuid";
import "jquery.easyui";
import "jquery.serializejson";
import KeyValuePairsDb, { KVPair, OperableStoreShow, ResultStatueCodeToText } from "../../logic/database/KeyValuePairsDb";
import Dialog, { DialogStatic, OptionGenerate_BaiscEditSaveDialog } from "../../logic/page/dialog";
import moment = require("moment");
import GetConfigJSON from "../../logic/network/config";

/** 时间格式 yyyy-MM-dd hh:mm:ss */
const MOMENT_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";

const db = new KeyValuePairsDb();

interface IPlan {
    /** Id 标识 */
    Id: string;
}
/** 简短计划信息 */
export interface ShortPlan extends IPlan {
    /** 计划标题 */
    Title: string;
    /** 重要等级 */
    ImportanceLevel: number;
    /** 顺序 */
    Sort?: number;
}
/** 可编辑的完整计划详情 */
export interface EditPlan extends ShortPlan {
    /** 需要完成的步骤数量 */
    NeedComplateCount: number;
    /** 描述备注 */
    DescribeRemark: string;
    /** 添加时间 (格式: yyyy-MM-dd hh:mm:ss) */
    AddTime: string;
}

async function get_edit_path_url() {
    let config = await GetConfigJSON();
    return `${config.BaseUrl}/functions/plan/edit.html`;
}
const edit_page_style = {
    width: "450px",
    height: "600px",
    padding: "10px 20px 0",
};

/**
 * 添加一个新的计划
 * @param store 数据操作区
 * @param callback 执行回调
 */
async function Add(store: OperableStoreShow, callback?: (model: EditPlan) => void) {
    let option: OptionGenerate_BaiscEditSaveDialog = {
        title: "添加一个新的计划",
        style: edit_page_style,
        url: await get_edit_path_url(),
        loadFunc: function (dialog: Dialog) {
            let form = dialog.GetDialog().find("form");
            form.form("load", {});
        },
        isSave: true,
        saveFunc: function (dialog: Dialog) {
            SaveAsync(store, dialog, callback);
        },
    };
    DialogStatic.ToGenerate_BaiscEditSaveDialog(option).Create().Open();
}

let EditLock_Save: boolean = false;
async function SaveAsync(store: OperableStoreShow, dialog: Dialog, callback?: (model: EditPlan) => void) {
    var form = dialog.GetDialog().find("form");
    form.form("submit", {
        onSubmit: function () {
            $(this).form("enableValidation");
            return false;
        },
    });
    if (!form.form("validate")) {
        return;
    }
    var model = form.serializeJSON() as EditPlan;
    if (!model.Id) {
        model.Id = uuidv4();
        console.log("create - model.Id:", model.Id);
    }
    if (!model.AddTime) {
        model.AddTime = moment().format(MOMENT_TIME_FORMAT);
    }

    if (EditLock_Save) {
        console.info("正在保存编辑内容, 锁定中...");
        return;
    }

    $.messager.progress({
        noheader: true,
        title: false,
        msg: "正在保存中...",
        interval: 100,
    });
    EditLock_Save = true;

    let dict: KVPair = {};
    dict[ToKEY_EditPlan(model.Id)] = model;

    let result = await db.Write(store.Name, dict);
    EditLock_Save = false;
    $.messager.progress("close");

    if (result.Code !== 0) {
        $.messager.alert({
            title: `错误: ${ResultStatueCodeToText(result.Code)}`,
            msg: `保存出错, 消息: ${result.Message}`,
            icon: "error",
        });
        return;
    }
    let success_count = result.Data;
    let dict_num = dict.Count();
    if (success_count !== dict_num) {
        $.messager.alert({
            title: "提示",
            msg: `预计更改数量: ${dict_num}, 实际更改数量: ${success_count}!`,
            icon: "error",
        });
        return;
    }
    // 更新计划名单
    await UpdateShortPlanAsync(store, model);
    $.messager.alert({
        title: "提示",
        msg: "保存成功",
        icon: "success",
    });
    dialog.Close();
    if (callback) {
        callback(model);
    }
}
function ToKEY_EditPlan(plan_id: string): string {
    return `plan:normal:${plan_id}`;
}

/**
 * 修改计划内容
 * @param store 数据操作区
 * @param plan_id 计划键名称
 */
async function Change(store: OperableStoreShow, plan_id: string, callback?: (model: EditPlan) => void) {
    let model = await GetPlanAsync(store, plan_id);
    if (!model || !model.Id) {
        $.messager.alert({
            title: "提示",
            msg: `查找计划: ${plan_id} 为空!`,
            icon: "error",
        });
        return;
    }
    let option: OptionGenerate_BaiscEditSaveDialog = {
        title: "修改计划",
        style: edit_page_style,
        url: await get_edit_path_url(),
        loadFunc: function (dialog: Dialog) {
            let form = dialog.GetDialog().find("form");
            form.form("load", model);
        },
        isSave: true,
        saveFunc: function (dialog: Dialog) {
            SaveAsync(store, dialog, callback);
        },
    };
    DialogStatic.ToGenerate_BaiscEditSaveDialog(option).Create().Open();
}

/**
 * 获取计划内容信息
 * @param store 数据操作区
 * @param plan_id 计划ID标识
 * @returns 返回计划内容信息
 */
async function GetPlanAsync(store: OperableStoreShow, plan_id: string): Promise<EditPlan> {
    let plan_key = ToKEY_EditPlan(plan_id);
    let result = await db.Read(store.Name, plan_key);
    if (result.Code !== 0) {
        $.messager.alert({
            title: `错误: ${ResultStatueCodeToText(result.Code)}`,
            msg: `获取计划内容信息出错, 消息: ${result.Message}`,
            icon: "error",
        });
        return null;
    }
    let dict: KVPair = result.Data;
    let model:EditPlan = dict[plan_key];
    return model;
}

/** 键名: 简短的计划清单 */
const KEY_ShortPlanList: string = "plan:list";
let shortPlanList: ShortPlan[] = null;

/**
 * 获取一份简短的计划清单
 * @param store 数据操作区
 * @returns 返回列表
 */
async function GetAShortPlanListAsync(store: OperableStoreShow): Promise<ShortPlan[]> {
    if (shortPlanList === null) {
        let result = await db.Read(store.Name, KEY_ShortPlanList);
        if (result.Code === 0) {
            let dict:KVPair = result.Data;
            shortPlanList = dict[KEY_ShortPlanList];
        } else {
            console.error(`错误: ${ResultStatueCodeToText(result.Code)}`);
            console.error(`获取计划名称列表出错, 消息: ${result.Message}`);
            shortPlanList = [];
        }
    }
    shortPlanList = sort_short_plan_list(shortPlanList);
    return shortPlanList;
}
/**
 * 更新计划信息
 * @param store 数据操作区
 * @param planInfo 计划信息
 * @returns 是否成功完成
 */
async function UpdateShortPlanAsync(store: OperableStoreShow, planInfo: ShortPlan): Promise<void> {
    let list = (await GetAShortPlanListAsync(store)) || [];
    let m: ShortPlan = {
        Id: planInfo.Id,
        Title: planInfo.Title,
        ImportanceLevel: planInfo.ImportanceLevel,
        Sort: planInfo.Sort,
    };

    let existence_index = -1;
    for (let index = 0; index < list.length; index++) {
        const item = list[index];
        if (item.Id === m.Id) {
            existence_index = index;
            break;
        }
    }
    if (existence_index > -1) {
        list[existence_index] = m;
    } else {
        list.push(m);
    }
    list = sort_short_plan_list(list);
    let dict:KVPair = {}
    dict[KEY_ShortPlanList] = list;

    let result = await db.Write(store.Name, dict);
    if (result.Code !== 0) {
        $.messager.alert({
            title: `错误: ${ResultStatueCodeToText(result.Code)}`,
            msg: `更新计划信息, 消息: ${result.Message}`,
            icon: "error",
        });
    }
}

function sort_short_plan_list(list: ShortPlan[]): ShortPlan[] {
    return list.sort((a, b) => {
        let num = a.ImportanceLevel - b.ImportanceLevel;
        num = num !== 0 ? num : (b.Sort || 0) - (a.Sort || 0);
        return num !== 0 ? num : -1;
    });
}

export default {
    Add,
    Change,
    GetPlanAsync,
    GetAShortPlanListAsync,
};
